package com.aisb.core.util.file;

import com.aisb.core.InitParam;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelUtils {
    private static Logger logger = LoggerFactory.getLogger(ExcelUtils.class);

    private Workbook wb;

    private static ExcelUtils _eu = null;

    public static ExcelUtils getInstance() {
        if (_eu == null) {
            _eu = new ExcelUtils();
        }
        return _eu;
    }

    public boolean createExcel(String fileName, List<Map> data) {
        List<String> title = getTitle(data);
        return createExcel(fileName, data, title);
    }

    public boolean createExcel(String fileName, List<Map> data, List<String> title) {
        try {
            if (!fileName.contains(".xls") && !fileName.contains(".xlsx")) {
                fileName += ".xlsx";
            }

            wb = createWorkbook(fileName);
            Sheet sheet = wb.createSheet(fileName);

            createTitle(sheet, title);
            createRowAll(sheet, data);

            // 设置默认行高
            sheet.setDefaultRowHeight((short) (20*20));
            // 自适应列宽度
            for (int i = 0; i < title.size(); i++) sheet.autoSizeColumn(i);
            // 隐藏网格线
            sheet.setDisplayGridlines(false);

            FileOutputStream fos = new FileOutputStream(InitParam.FILE_PATH_DOWNLOAD + fileName);
            wb.write(fos);
            fos.close();

        } catch (Exception e) {
            logger.error("{}", e);
            return false;
        }

        return true;
    }

    private Workbook createWorkbook(String fileName) throws Exception {
        Workbook wb = null;

        if (fileName.endsWith(".xls")) {
            wb = new HSSFWorkbook();
        } else if (fileName.endsWith(".xlsx")) {
            wb = new XSSFWorkbook();
        } else {
            throw new Exception("文件类型错误！");
        }

        return wb;
    }

    private List<String> getTitle(List<Map> data) {
        List<String> title = new ArrayList<>();

        if (null != data && !data.isEmpty()) {
            Map m = data.get(0);
            for (Object key : m.keySet()) {
                title.add((String) key);
            }
        }

        return title;
    }

    private void createTitle(Sheet sheet, List<String> title) {
        Row row = sheet.getRow(0);

        if (null == row) {
            row = sheet.createRow(0);
        }

        row.setHeight((short) (30*20));

        CellStyle cellStyle = getHeadCellStyle();

        for (int i = 0; i < title.size(); i++) {
            createCell(row, i, title.get(i), cellStyle);
        }
    }

    private void createRowAll(Sheet sheet, List<Map> data) {
        for (int i = 0; i < data.size(); i++) {
            createRow(sheet, (i + 1), data.get(i));
        }
    }

    private void createRow(Sheet sheet, int rowNum, Map rowData) {
        Row row = sheet.getRow(rowNum);

        if (row == null) {
            row = sheet.createRow(rowNum);
        }

        row.setHeight((short) (25 * 20));

        CellStyle cellStyle = getCellStyle();

        List<String> mapKeyList = new ArrayList<String>(rowData.keySet());
        for (int i = 0; i < mapKeyList.size(); i++) {
            createCell(row, i, rowData.get(mapKeyList.get(i)), cellStyle);
        }
    }

    private void createCell(Row row, int cellNum, Object cellData, CellStyle cellStyle) {
        Cell cell = row.getCell(cellNum);

        if (cell == null) {
            cell = row.createCell(cellNum);
        }

        if(null != cellStyle){
            cell.setCellStyle(cellStyle);
        }

        cell.setCellValue((String) cellData);
    }

    private CellStyle getCellStyle() {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);

        // 设置对齐方式
        style.setAlignment(HorizontalAlignment.LEFT);
        style.setVerticalAlignment(VerticalAlignment.CENTER);

        // 设置边框和颜色
        style.setBottomBorderColor(IndexedColors.DARK_TEAL.index);
        style.setTopBorderColor(IndexedColors.DARK_TEAL.index);
        style.setLeftBorderColor(IndexedColors.DARK_TEAL.index);
        style.setRightBorderColor(IndexedColors.DARK_TEAL.index);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        return style;
    }

    private CellStyle getHeadCellStyle() {
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("宋体");
        font.setColor(HSSFColor.WHITE.index);
        font.setFontHeightInPoints((short) 14);
        font.setBold(true);
        style.setFont(font);

        // 设置对齐方式
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);

        // 设置背景颜色
        style.setFillForegroundColor(IndexedColors.DARK_TEAL.index);
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        // 设置边框和颜色
        style.setBottomBorderColor(IndexedColors.DARK_TEAL.index);
        style.setTopBorderColor(IndexedColors.DARK_TEAL.index);
        style.setLeftBorderColor(IndexedColors.DARK_TEAL.index);
        style.setRightBorderColor(IndexedColors.DARK_TEAL.index);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        return style;
    }

    public static void main(String[] args){
        Map m = new HashMap();
        m.put("sdfsdfsadf", "sdfasdfasdfasdf");
        m.put("你好你好你好你好你好你好", "你好你好你好你好你好你好你好你好");
        List list = new ArrayList();
        list.add(m);
        ExcelUtils.getInstance().createExcel("a"+System.currentTimeMillis(), list);
    }
}
